<template>
    <div class="relative w-full h-full">
        <img ref="img" :class="[objectMode, { invisible: isError }]" :style="{
            width,
            height
        }" :src="loading" />
        <slot name="error">
            <div v-if="isError" class="absolute inset-0 grid text-sm text-gray-400 bg-gray-100 place-content-center">
                <IIcon-park-outline:damage-map class="w-8 h-8" />
            </div>
        </slot>
    </div>
</template>
    
<script setup lang='ts'>
import { useIntersectionObserver } from '@vueuse/core';
import loading from '~/assets/loading.gif'
const { size, mode, src } = withDefaults(
    defineProps<{
        src: string;
        size?: {
            width: number;
            height: number;
        },
        mode?: 'cover' | 'contain'
    }>(),
    {
        mode: 'cover'
    }
)
const img = ref<HTMLImageElement>();
const width = ref('100%')
const height = ref('100%');
const isError = ref(false)
const modes = {
    'cover': 'object-cover',
    'contain': 'object-contain'
}
const objectMode = modes[mode] || modes.cover;
const setSize = () => {
    if (!size) return;
    const el = unref(img) as HTMLImageElement;
    const w = el.parentElement!.offsetWidth;
    const h = size.height / size.width * w
    width.value = w + 'px'
    height.value = h + 'px'
}
onMounted(() => {
    const el = unref(img) as HTMLImageElement;
    const { stop } = useIntersectionObserver(
        el,
        ([{ isIntersecting }]) => {
            if (!isIntersecting) {
                return
            }
            stop();
            setSize();
            setTimeout(() => {
                el!.src = src
            }, 100);
            el.onerror = () => {
                isError.value = true;
            }
        },
    )
})
</script>
    
<style></style>